# -*- coding:utf-8 -*-
from lxml import html
import os
import re

from selenium import webdriver
import time

OVER_TIME = 5
BASE_URL = "https://passport.cnblogs.com/user/signin?ReturnUrl=https%3A%2F%2Fwww.cnblogs.com%2F"


class Driver(object):

    def __new__(cls, *args, **kw):
        """
        使用单例模式将类设置为运行时只有一个实例，在其他Python类中使用基类时，
        可以创建多个对象，保证所有的对象都是基于一个浏览器
        """
        if not hasattr(cls, '_instance'):
            orig = super(Driver, cls)
            cls._instance = orig.__new__(cls, *args, **kw)
        return cls._instance

    def start(self, url=BASE_URL, driver_name="Chrome"):
        """
        启动浏览器
        :param url: 测试地址
        :param driver_name: 在启动时设置浏览器的类型
        :return:
        """
        if driver_name == "Firefox":
            self.driver = webdriver.Firefox()
        elif driver_name == "Ie":
            self.driver = webdriver.Ie()
        else:
            self.driver = webdriver.Chrome()
        self.driver.implicitly_wait(OVER_TIME)
        self.driver.get(url)
        self.driver.maximize_window()

    def get_url(self):
        """返回浏览器的地址"""
        return BASE_URL

    def find_element(self, by, value):
        """
        这里添加了一个OVER_TIME作为查找元素的超时次数，根据系统的实际情况设置OVER_TIME的大小
        """
        for i in range(OVER_TIME):
            try:
                return self.driver.find_element(by=by, value=value)
            except Exception as e:
                print(e)

    def find_elements(self, by, value):
        """与find_element一致"""
        for i in range(OVER_TIME):
            try:
                return self.driver.find_elements(by=by, value=value)
            except Exception as e:
                print(e)

    def find_display_elements(self, by, value):
        """
        查找状态为displayed的元素集合，当查找一类元素时，
        经常出现有些元素是不可见的情况，此函数屏蔽那些不可见的元素
        """
        for i in range(OVER_TIME):
            try:
                elements = self.driver.find_elements(by=by, value=value)
                num = elements.__len__()
            except Exception as e:
                print(e)
                time.sleep(1)
            if num >= 1:
                break
        display_element = []
        # 将可见的元素放到列表中， 并返回
        for j in range(num):
            element = elements.__getitem__(j)
            if element.is_displayed():
                display_element.append(element)
        return display_element

    def is_element_present(self, By, Value):
        """判断元素是否存在"""
        try:
            self.driver.find_element(by=By, value=Value)
            return True
        except Exception as e:
            print(e)
            return False

    def close(self):
        self.driver.close()

    def quit(self):
        u"""退出浏览器"""
        self.driver.quit()

    def getElement(self, selector):
        """
        to locate element by selector
        :arg
        selector should be passed by an example with "i,xxx"
        "x,//*[@id='langs']/button"
        :returns
        DOM element
        """
        if ',' not in selector:
            return self.driver.find_element_by_id(selector)
        selector_by = selector.split(',')[0]
        selector_value = selector.split(',')[1]

        if selector_by == "i" or selector_by == 'id':
            element = self.driver.find_element_by_id(selector_value)
        elif selector_by == "n" or selector_by == 'name':
            element = self.driver.find_element_by_name(selector_value)
        elif selector_by == "c" or selector_by == 'class_name':
            element = self.driver.find_element_by_class_name(selector_value)
        elif selector_by == "l" or selector_by == 'link_text':
            element = self.driver.find_element_by_link_text(selector_value)
        elif selector_by == "p" or selector_by == 'partial_link_text':
            element = self.driver.find_element_by_partial_link_text(selector_value)
        elif selector_by == "t" or selector_by == 'tag_name':
            element = self.driver.find_element_by_tag_name(selector_value)
        elif selector_by == "x" or selector_by == 'xpath':
            element = self.driver.find_element_by_xpath(selector_value)
        elif selector_by == "s" or selector_by == 'selector_selector':
            element = self.driver.find_element_by_css_selector(selector_value)
        else:
            raise NameError("Please enter a valid type of targeting elements.")

        return element

    def type(self, selector, text):
        """
        Operation input box.

        Usage:
        driver.type("i,el","selenium")
        """
        el = self.getElement(selector)
        el.clear()
        el.send_keys(text)


def send_request(driver, url, params, method='POST'):
    file_path = os.path.abspath(os.path.dirname(__file__))
    if method == 'GETx':
        parm_str = ''
        for key, value in params.items():
            parm_str = parm_str + key + '=' + str(value) + '&'
            if parm_str.endswith('&'):
                parm_str = '?' + parm_str[:-1]
        driver.get(url + parm_str)
    else:
        jquery = open(file_path + "/js/jquery-2.2.3.min.js", "r").read()
        driver.execute_script(jquery)
        ajax_query = '''
                    $.ajax('%s', {
                    type: '%s',
                    data: %s, 
                    crossDomain: true,
                    xhrFields: {
                     withCredentials: true
                    },
                    success: function(){}
                    });
                    ''' % (url, method, params)

        ajax_query = ajax_query.replace(" ", "").replace("\n", "")
        resp = driver.execute_script("return " + ajax_query)
        return resp


import requests

defaultHeader = {"Accept": "application/json, text/javascript, */*; q=0.01",
                 "Accept-Encoding": "gzip, deflate, br",
                 "Accept-Language": "zh-CN,zh;q=0.9",
                 "Connection": "keep-alive",
                 "Referer": "https://developer.rongcloud.cn/app/user/cqF9CV-GhGmUirgCniUrqA?userId=",
                 "Sec-Fetch-Mode": "cors",
                 "Sec-Fetch-Site": "same-origin",
                 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36",
                 "X-Requested-With": "XMLHttpRequest"}


def drv2session(xdriver):
    # 创建一个requests session对象
    xsession = requests.Session()
    # 从driver中获取cookie列表（是一个列表，列表的每个元素都是一个字典）
    cookies = xdriver.get_cookies()

    # # 把cookies设置到session中
    for cookie in cookies:
        # cookiejar.set(cookie['name'], cookie['value'], domain=cookie['domain'], path=cookie['path'])
        xsession.cookies.set(cookie['name'], cookie['value'], domain=cookie['domain'])
    return xsession


def drv_req_get(xdriver, url, xheaders=defaultHeader):
    """
    传入webdriver 执行URL get

    会自动导入webdriver的cookis
    """

    # 创建一个requests session对象
    xsession = drv2session(xdriver)

    return xsession.get(url, headers=xheaders)
    # # headers = xdriver.get_headers()
    # # for header in headers:
    # #     s.headers
    #
    # # 需要登录才能看到的页面URL
    # page_url = 'https://www.douban.com/accounts/'
    # # 获取该页面的HTML
    # resp = s.get(page_url)
    # resp.encoding = 'utf-8'
    # print
    # 'status_code = {0}'.format(resp.status_code)
    # # 将网页内容存入文件
    # with open('html.txt', 'w+') as  fout:
    #     fout.write(resp.text)


def drv_req_post(xdriver, url, data=None, json=None, xheaders=defaultHeader):
    """
    传入webdriver 执行URL POST

    会自动导入webdriver的cookis
    """
    xsession = drv2session(xdriver)

    return xsession.post(url, data, json, headers=xheaders)

def getHTML_Element(xdriver, xpath, itemname = 'value'):
    tree = html.document_fromstring( xdriver.page_source)
    xitem = tree.xpath(xpath)
    return xitem[0].get(itemname)


def getSource(xdriver, LB='<input type=\"hidden\" name=\"id\" class=\"appId\" value=\"',
              RB='\" />'):
    """
    在网页源码中 查找 LB、RB 包围的text
    """
    page = xdriver.page_source
    vlist = re.findall(LB + '(.*?)' + RB, page, re.S)

    return vlist[0]


if __name__ == "__main__":
    page = Driver()
    page.start()
